home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint104s.zoo
/
mint.src
/
pipefs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-08
|
26KB
|
1,061 lines
/*
Copyright 1991,1992 Eric R. Smith.
Copyright 1992 Atari Corporation.
All rights reserved.
*/
/* simple pipefs.c */
#include "mint.h"
static int pipetime, pipedate; /* root directory time/date stamp */
static long ARGS_ON_STACK pipe_root P_((int drv, fcookie *fc));
static long ARGS_ON_STACK pipe_lookup P_((fcookie *dir, const char *name, fcookie *fc));
static long ARGS_ON_STACK pipe_getxattr P_((fcookie *file, XATTR *xattr));
static long ARGS_ON_STACK pipe_chattr P_((fcookie *file, int attrib));
static long ARGS_ON_STACK pipe_chown P_((fcookie *file, int uid, int gid));
static long ARGS_ON_STACK pipe_chmode P_((fcookie *file, unsigned mode));
static long ARGS_ON_STACK pipe_rmdir P_((fcookie *dir, const char *name));
static long ARGS_ON_STACK pipe_remove P_((fcookie *dir, const char *name));
static long ARGS_ON_STACK pipe_getname P_((fcookie *root, fcookie *dir,
char *pathname, int size));
static long ARGS_ON_STACK pipe_rename P_((fcookie *olddir, char *oldname,
fcookie *newdir, const char *newname));
static long ARGS_ON_STACK pipe_opendir P_((DIR *dirh, int flags));
static long ARGS_ON_STACK pipe_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *));
static long ARGS_ON_STACK pipe_rewinddir P_((DIR *dirh));
static long ARGS_ON_STACK pipe_closedir P_((DIR *dirh));
static long ARGS_ON_STACK pipe_pathconf P_((fcookie *dir, int which));
static long ARGS_ON_STACK pipe_dfree P_((fcookie *dir, long *buf));
static long ARGS_ON_STACK pipe_creat P_((fcookie *dir, const char *name, unsigned mode,
int attrib, fcookie *fc));
static DEVDRV * ARGS_ON_STACK pipe_getdev P_((fcookie *fc, long *devsp));
static long ARGS_ON_STACK pipe_open P_((FILEPTR *f));
static long ARGS_ON_STACK pipe_write P_((FILEPTR *f, const char *buf, long bytes));
static long ARGS_ON_STACK pipe_read P_((FILEPTR *f, char *buf, long bytes));
static long ARGS_ON_STACK pipe_lseek P_((FILEPTR *f, long where, int whence));
static long ARGS_ON_STACK pipe_ioctl P_((FILEPTR *f, int mode, void *buf));
static long ARGS_ON_STACK pipe_datime P_((FILEPTR *f, short *time, int rwflag));
static long ARGS_ON_STACK pipe_close P_((FILEPTR *f, int pid));
static long ARGS_ON_STACK pipe_select P_((FILEPTR *f, long p, int mode));
static void ARGS_ON_STACK pipe_unselect P_((FILEPTR *f, long p, int mode));
DEVDRV pipe_device = {
pipe_open, pipe_write, pipe_read, pipe_lseek, pipe_ioctl, pipe_datime,
pipe_close, pipe_select, pipe_unselect
};
/* ptys and pipes can share the same driver, for now */
#define pty_device pipe_device
FILESYS pipe_filesys = {
(FILESYS *)0,
0,
pipe_root,
pipe_lookup, pipe_creat, pipe_getdev, pipe_getxattr,
pipe_chattr, pipe_chown, pipe_chmode,
nomkdir, pipe_rmdir, pipe_remove, pipe_getname, pipe_rename,
pipe_opendir, pipe_readdir, pipe_rewinddir, pipe_closedir,
pipe_pathconf, pipe_dfree,
nowritelabel, noreadlabel, nosymlink, noreadlink,
nohardlink, nofscntl, nodskchng
};
/* size of pipes */
#define PIPESIZ 4096 /* MUST be a multiple of 4 */
/* writes smaller than this are atomic */
#define PIPE_BUF 1024 /* should be a multiple of 4 */
/* magic flag: indicates that nobody but the creator has opened this pipe */
/* note: if this many processes open the pipe, we lose :-( */
#define VIRGIN_PIPE 0x7fff
struct pipe {
int readers; /* number of readers of this pipe */
int writers; /* number of writers of this pipe */
int head, tail; /* pipe head, tail (head == tail for empty) */
long rsel; /* process that did select() for reads */
long wsel; /* process that did select() for writes */
char buf[PIPESIZ]; /* pipe data */
};
struct fifo {
char name[NAME_MAX+1]; /* FIFO's name */
short date, time; /* date & time of last write */
short dosflags; /* DOS flags, e.g. FA_RDONLY, FA_HIDDEN */
ushort mode; /* file access mode, for XATTR */
ushort uid, gid; /* file owner; uid and gid */
short flags; /* various other flags (e.g. O_TTY) */
short lockpid; /* pid of locking process */
short cursrate; /* cursor flash rate for pseudo TTY's */
struct tty *tty; /* tty struct for pseudo TTY's */
struct pipe *inp; /* pipe for reads */
struct pipe *outp; /* pipe for writes (0 if unidirectional) */
struct fifo *next; /* link to next FIFO in list */
FILEPTR *open; /* open file pointers for this fifo */
} *rootlist;
static long ARGS_ON_STACK
pipe_root(drv, fc)
int drv;
fcookie *fc;
{
if (drv == PIPEDRV) {
fc->fs = &pipe_filesys;
fc->dev = drv;
fc->index = 0L;
return 0;
}
fc->fs = 0;
return EINTRN;
}
static long ARGS_ON_STACK
pipe_lookup(dir, name, fc)
fcookie *dir;
const char *name;
fcookie *fc;
{
struct fifo *b;
TRACE(("pipe_lookup(%s)", name));
if (dir->index != 0) {
DEBUG(("pipe_lookup(%s): bad directory", name));
return EPTHNF;
}
/* special case: an empty name in a directory means that directory */
/* so does "." */
if (!*name || (name[0] == '.' && name[1] == 0)) {
*fc = *dir;
return 0;
}
/* another special case: ".." could be a mount point */
if (!strcmp(name, "..")) {
*fc = *dir;
return EMOUNT;
}
for (b = rootlist; b; b = b->next) {
if (!strnicmp(b->name, name, NAME_MAX)) {
fc->fs = &pipe_filesys;
fc->index = (long)b;
fc->dev = dir->dev;
return 0;
}
}
DEBUG(("pipe_lookup: name `%s' not found", name));
return EFILNF;
}
static long ARGS_ON_STACK
pipe_getxattr(fc, xattr)
fcookie *fc;
XATTR *xattr;
{
struct fifo *this;
xattr->index = fc->index;
xattr->dev = fc->dev;
xattr->nlink = 1;
xattr->blksize = 1;
if (fc->index == 0) { /* root directory? */
xattr->uid = xattr->gid = 0;
xattr->mtime = xattr->atime = xattr->ctime = pipetime;
xattr->mdate = xattr->adate = xattr->cdate = pipedate;
xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
xattr->attr = FA_DIR;
xattr->size = xattr->nblocks = 0;
} else {
this = (struct fifo *)fc->index;
xattr->uid = this->uid;
xattr->gid = this->gid;
xattr->mtime = xattr->atime = xattr->ctime = this->time;
xattr->mdate = xattr->adate = xattr->cdate = this->date;
xattr->mode = this->mode;
xattr->attr = this->dosflags;
/* note: fifo's that haven't been opened yet can be written to */
if (this->flags & O_HEAD) {
xattr->attr &= ~FA_RDONLY;
}
xattr->nblocks = PIPESIZ;
if (this->dosflags & FA_SYSTEM) { /* pseudo-tty */
xattr->size = PIPESIZ/4;
} else {
xattr->size = PIPESIZ;
}
}
return 0;
}
static long ARGS_ON_STACK
pipe_chattr(fc, attrib)
fcookie *fc;
int attrib;
{
UNUSED(fc); UNUSED(attrib);
return EACCDN;
}
static long ARGS_ON_STACK
pipe_chown(fc, uid, gid)
fcookie *fc;
int uid, gid;
{
struct fifo *this;
if ((this = (struct fifo *)fc->index) == 0)
return EACCDN;
this->uid = uid;
this->gid = gid;
return 0;
}
static long ARGS_ON_STACK
pipe_chmode(fc, mode)
fcookie *fc;
unsigned mode;
{
struct fifo *this;
if ((this = (struct fifo *)fc->index) == 0)
return EACCDN;
this->mode = (this->mode & S_IFMT) | (mode & ~S_IFMT);
return 0;
}
static long ARGS_ON_STACK
pipe_rmdir(dir, name)
fcookie *dir;
const char *name;
{
UNUSED(dir); UNUSED(name);
/* the kernel already checked to see if the file exists */
return EACCDN;
}
static long ARGS_ON_STACK
pipe_remove(dir, name)
fcookie *dir;
const char *name;
{
UNUSED(dir); UNUSED(name);
/* the kernel already checked to see if the file exists */
return EACCDN;
}
static long ARGS_ON_STACK
pipe_getname(root, dir, pathname, size)
fcookie *root, *dir; char *pathname;
int size;
{
UNUSED(root);
UNUSED(size); /* BUG: we should support 'size' */
if (dir->index == 0)
*pathname = 0;
else
strcpy(pathname, ((struct fifo *)dir->index)->name);
return 0;
}
static long ARGS_ON_STACK
pipe_rename(olddir, oldname, newdir, newname)
fcookie *olddir;
char *oldname;
fcookie *newdir;
const char *newname;
{
UNUSED(olddir); UNUSED(oldname);
UNUSED(newdir); UNUSED(newname);
return EACCDN;
}
static long ARGS_ON_STACK
pipe_opendir(dirh, flags)
DI